


#ifndef __METRIC_H__
#define __METRIC_H__



typedef double metric_dt;
typedef unsigned int metric_sec;
typedef long long metric_st;
typedef unsigned long long metric_ut;
typedef unsigned long long metric_pts;

typedef void (*metric_tp_fn)(double dv);

#define METRIC_BPS_FMT  "%.04f"

typedef struct
{
    metric_dt val;
    metric_dt min;
    metric_dt max;
    metric_dt acc;
    metric_dt mea;
} metric_dv;    /* double value */

typedef struct
{
    metric_ut val;
    metric_ut min;
    metric_ut max;
    metric_ut acc;
    metric_ut mea;
} metric_uv;    /* unsigned value */

typedef struct
{
    metric_st val;
    metric_st min;
    metric_st max;
    metric_st acc;
    metric_st mea;
} metric_sv;    /* signed value */

typedef struct
{
    metric_pts val;
    metric_pts min;
    metric_pts max;
    metric_pts acc;
    metric_pts mea;
} metric_tv;    /* pts value */

/* Throughput Metric */
typedef struct
{
    metric_ut  count;
    metric_ut  bytes;
    metric_pts pts;
    metric_sec period;      /* second */
    metric_dv  tp;          /* bps */
    metric_tp_fn period_fn;
} metric_tp;

/* Operation Metric */
typedef struct
{
    metric_ut  count;
    metric_uv  bytes;
    metric_pts start;
    metric_dv  tp;          /* bps */
    metric_tv  lantacy;     /* us */
} metric_op;



#define METRIC_LAT(m)   (m.lantacy)
#define METRIC_TP(m)    (m.tp)
#define METRIC_BYTES(m) (m.bytes)
#define METRIC_VAL(v)   (v.val)
#define METRIC_VMIN(v)  (v.min)
#define METRIC_VMAX(v)  (v.max)
#define METRIC_VACC(v)  (v.acc)
#define METRIC_VMEA(v)  (v.mea)

void metric_tp_init(metric_tp *metric, metric_sec period_second, 
    metric_tp_fn period_fn);

void metric_tp_update(metric_tp *metric, metric_ut bytes);

void metric_op_init(metric_op *metric);
void metric_op_start(metric_op *metric);
void metric_op_stop(metric_op *metric, metric_ut bytes);

char *metric_bps_str(metric_dt bits);
char *metric_bytes_str(metric_ut bytes);
char *metric_pts_str(metric_pts pts);


#endif /* __METRIC_H__ */